package cn.pugle.selenium.dailywork;

import cn.pugle.poi.POIUtils;
import cn.pugle.selenium.SeleUtil;
import com.alibaba.fastjson.JSON;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static cn.pugle.selenium.SeleUtil.*;

/**
 * -Dwebdriver.chrome.driver="C:\\Users\\tzp\\Download\\chromedriver.exe"
 * workpath C:\Users\tzp\Projects\CodeAccumulate\src\main\resources
 * Created by tzp on 6/8/16.<br>
 */
public class DailyReport {
    private static Logger logger = LoggerFactory.getLogger(DailyReport.class);

    /**
     * 填到excel里时的日期格式
     */
    private static DateTimeFormatter dateFormatExcel = DateTimeFormatter.ofPattern("MM月dd日");

    public static void main(String[] args) throws IOException, InvalidFormatException {
        if (args.length != 1) {
            logger.error("usage: java -cp xx/* cn.pugle.selenium.dailywork.DailyReport -Dwebdriver.chrome.driver=xx.exe workpath");
            System.exit(1);
        }
        String workpath = args[0];
        RemoteWebDriver driver = SeleUtil.chromeDriver;

        List<DSPConfig> dspConfigs = JSON.parseArray(FileUtils.readFileToString(
                new File(workpath, "selenium_dailywork.json"), Default_Charset), DSPConfig.class);
        File outFile = new File(workpath, "DailyReport.xlsx");
        XSSFWorkbook excel = new XSSFWorkbook(outFile);

        for (DSPConfig dspConfig : dspConfigs) {
            try {
                driver.get(dspConfig.startUrl);
                /** login */
                //有的网页需要点击按钮出现登录框
                if (StringUtils.isNotBlank(dspConfig.beforeloginButtonBy)) {
                    WebElement beforeLoginButton = waitElementPresent(by(dspConfig.beforeloginButtonBy));
                    beforeLoginButton.click();
                }
                //用户名 密码 登录按钮
                WebElement userNmEle = waitElementPresent(by(dspConfig.userNmBy));
                WebElement passWdEle = waitElementPresent(by(dspConfig.passWdBy));
                WebElement loginButton = waitElementPresent(by(dspConfig.loginButtonBy));
                //有jq的话，用js填写表单，没有的sendkeys
                if (dspConfig.isJQEnable) {
                    driver.executeScript("$(\"" + dspConfig.userNmBy + "\").val(\"" + dspConfig.userNm + "\")");
                    driver.executeScript("$(\"" + dspConfig.passWdBy + "\").val(\"" + dspConfig.passWd + "\")");
                } else {
                    userNmEle.click();
                    userNmEle.sendKeys(dspConfig.userNm);
                    passWdEle.click();
                    passWdEle.sendKeys(dspConfig.passWd);
                }
                //有验证码的话，需要手动填写验证码点击登录，没有的话程序登录
                if (dspConfig.loginWithCaptcha) {
                    waitElementDisappear(by(dspConfig.loginButtonBy), 60 * 60);
                } else {
                    loginButton.click();
                }
                logger.info("{} login success, jq {} captcha {}", new Object[]{dspConfig.name, dspConfig.isJQEnable, dspConfig.loginWithCaptcha});
                //login end

                /** steps */
                for (Map<String, String> step : dspConfig.steps) {
                    String location = step.get("location");
                    if (step.get("type").equals("get")) {
                        driver.get(location);
                    } else if (step.get("type").equals("click")) {
                        WebElement webElement = waitElementPresent(by(location));
                        webElement.click();
                    }
                }

                /** report */
                Map<Integer, String> report = new HashMap<>();//key是在excel里的列index
                DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern(dspConfig.cpXDateForm);
                String yesterday = LocalDateTime.now().minusDays(1).format(dateFormat);

                if (!dspConfig.cpXJson) {
                    //date
                    WebElement cpXDateEle = waitElementPresent(by(dspConfig.cpXDateBy));
                    String text = cpXDateEle.getText();
//                  if (!text.equals(yesterday)) {
//                        throw new Exception("cpXDate wrong");
//                  }
                    report.put(dspConfig.dateCol, yesterday);
                    //cpc
                    if (StringUtils.isNotEmpty(dspConfig.cpcNumBy)) {
                        WebElement cpcNumEle = waitElementPresent(by(dspConfig.cpcNumBy));
                        String cpcNum = cpcNumEle.getText();
                        if (!isNum(cpcNum)) {
                            throw new Exception("cpc text not numeric");
                        }
                        report.put(dspConfig.cpcNumCol, cpcNum);
                    }
                    //cpd
                    if (StringUtils.isNotEmpty(dspConfig.cpdNumBy)) {
                        WebElement cpdNumEle = waitElementPresent(by(dspConfig.cpdNumBy));
                        String cpdNum = cpdNumEle.getText();
                        if (!isNum(cpdNum)) {
                            throw new Exception("cpd text not numeric");
                        }
                        report.put(dspConfig.cpdNumCol, cpdNum);
                    }
                    //cpm
                    if (StringUtils.isNotEmpty(dspConfig.cpmNumBy)) {
                        WebElement cpmNumEle = waitElementPresent(by(dspConfig.cpmNumBy));
                        String cpmNum = cpmNumEle.getText();
                        if (!isNum(cpmNum)) {
                            throw new Exception("cpm text not numeric");
                        }
                        report.put(dspConfig.cpmNumCol, cpmNum);
                    }
                    //totalCost
                    WebElement totalCostEle = waitElementPresent(by(dspConfig.totalCostBy));
                    String totalCost = totalCostEle.getText();
                    if (!isNum(totalCost)) {
                        throw new Exception("totalCost text not numeric");
                    }
                    report.put(dspConfig.totalCostCol, totalCost);
                } else {
                    if (dspConfig.isJQEnable) {
                        //$.post("{cpXJsonUrl}", "{cpXJsonBody}", function(data,status){
                        // $("body").append("<div id='seleniumtrick1'>" + JSON.stringify(data) + "<div/>")});
                        final String cpXJSTemplate = "";
                        String body = dspConfig.cpXJsonBody.replace("{startDate}", "")
                                .replace("{endDate}", yesterday);
                        String jsCMD = cpXJSTemplate.replace("{cpXJsonUrl}", dspConfig.cpXJsonUrl)
                                .replace("{cpXJsonBody}", body);
                        driver.executeScript(jsCMD);
                        WebElement trickElement = waitElementPresent(by("#seleniumtrick1"));
                        String jsonResult = trickElement.getText();

                    } else {//todo 需要从json获取数据,但是没有jquery

                    }
                }

                /**fill the excel*/
                XSSFSheet sheet = excel.getSheetAt(dspConfig.sheetIndex);
                int lastRowNum = sheet.getLastRowNum();
                XSSFRow lastRow = sheet.getRow(lastRowNum);
                XSSFRow newRow = sheet.createRow(lastRowNum + 1);
                report.put(dspConfig.formulaIndex,
                        dspConfig.formula.replace("{line}", String.valueOf(lastRowNum + 1)));
                String[] sameIndexs = dspConfig.sameIndexs.split(",");
                for (String sameIndex : sameIndexs) {
                    Integer sameCol = Integer.valueOf(sameIndex);
                    report.put(sameCol, POIUtils.getSingleCellValue(lastRow.getCell(sameCol)));
                }

                fillCell(newRow, lastRow, report);

                sheet.setForceFormulaRecalculation(true);
                File reportFile = new File(workpath + "\\bak", yesterday + "bak.xlsx");
                excel.write(new FileOutputStream(reportFile));
                excel.close();
            } catch (Exception e) {
                e.printStackTrace();
                logger.error(dspConfig.name + " error", e);
                //todo send mail
            }
        }
        driver.close();
        System.exit(0);
    }


    /**
     * 按照上一行的stype在新一行的指定列创建cell
     *
     * @param report key是cell index， value是要填的值
     */
    private static void fillCell(XSSFRow newRow, XSSFRow lastRow, Map<Integer, String> report) {
        for (Map.Entry<Integer, String> entry : report.entrySet()) {
            Integer cellIndex = entry.getKey();
            String value = entry.getValue();

            XSSFCell lastCell = lastRow.getCell(cellIndex);
            POIUtils.createCell(newRow, cellIndex,
                    lastCell.getCellType(), lastCell.getCellStyle(), value);
        }
    }

    private static boolean isNum(String str) {
        try {
            Double.parseDouble(str);
        } catch (NumberFormatException nfe) {
            return false;
        }
        return true;
    }
}
